package com.lineage.data.item_etcitem;

import com.lineage.config.Config;
import com.lineage.data.executor.ItemExecutor;
import com.lineage.server.datatables.CharObjidTable;
import com.lineage.server.datatables.ItemTable;
import com.lineage.server.datatables.lock.CharItemsReading;
import com.lineage.server.datatables.sql.CharacterTable;
import com.lineage.server.datatables.sql.LetterTable;
import com.lineage.server.model.Instance.L1ItemInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.L1Clan;
import com.lineage.server.serverpackets.S_ServerMessage;
import com.lineage.server.serverpackets.S_SkillSound;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.world.World;
import com.lineage.server.world.WorldClan;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Iterator;
import java.util.TimeZone;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Clan_Letter extends ItemExecutor {
  private static final Log _log = LogFactory.getLog(Clan_Letter.class);
  
  public static ItemExecutor get() {
    return new Clan_Letter();
  }
  
  public void execute(int[] data, L1PcInstance pc, L1ItemInstance item) {
    int itemId = item.getItemId();
    int letterCode = data[0];
    String letterReceiver = pc.getText();
    byte[] letterText = pc.getTextByte();
    if (writeClanLetter(itemId, pc, letterCode, letterReceiver, letterText))
      pc.getInventory().removeItem(item, 1L); 
  }
  
  private boolean writeClanLetter(int itemId, L1PcInstance pc, int letterCode, String letterReceiver, byte[] letterText) {
    L1Clan targetClan = null;
    Collection<L1Clan> allClans = WorldClan.get().getAllClans();
    Iterator<L1Clan> iter = allClans.iterator();
    while (iter.hasNext()) {
      L1Clan clan = iter.next();
      if (clan.getClanName().toLowerCase().equals(letterReceiver.toLowerCase())) {
        targetClan = clan;
        break;
      } 
    } 
    if (targetClan == null) {
      pc.sendPackets((ServerBasePacket)new S_ServerMessage(434));
      return false;
    } 
    String[] memberName = targetClan.getAllMembers();
    int i = 0;
    while (i < memberName.length) {
      L1ItemInstance item = ItemTable.get().createItem(49016);
      if (item == null)
        return false; 
      item.setCount(1L);
      if (sendLetter(pc, memberName[i], item, false))
        saveLetter(item.getId(), letterCode, pc.getName(), memberName[i], letterText); 
      i++;
    } 
    return true;
  }
  
  private boolean sendLetter(L1PcInstance pc, String name, L1ItemInstance item, boolean isFailureMessage) {
    L1PcInstance target = World.get().getPlayer(name);
    if (target == null) {
      if (CharacterTable.doesCharNameExist(name))
        try {
          int objid = CharObjidTable.get().charObjid(name);
          CopyOnWriteArrayList<L1ItemInstance> list = CharItemsReading.get()
            .loadItems(Integer.valueOf(objid));
          if (list.size() < 180) {
            CharItemsReading.get().storeItem(objid, item);
            return true;
          } 
          if (isFailureMessage)
            pc.sendPackets((ServerBasePacket)new S_ServerMessage(942)); 
          return false;
        } catch (Exception e) {
          _log.error(e.getLocalizedMessage(), e);
          return true;
        }  
      if (isFailureMessage)
        pc.sendPackets((ServerBasePacket)new S_ServerMessage(109, name)); 
      return false;
    } 
    if (target.getInventory().checkAddItem(item, 1L) != 0) {
      if (isFailureMessage)
        pc.sendPackets((ServerBasePacket)new S_ServerMessage(942)); 
      return false;
    } 
    target.getInventory().storeItem(item);
    target.sendPackets((ServerBasePacket)new S_SkillSound(target.getId(), 1091));
    target.sendPackets((ServerBasePacket)new S_ServerMessage(428));
    return true;
  }
  
  private void saveLetter(int itemObjectId, int code, String sender, String receiver, byte[] text) {
    SimpleDateFormat sdf = new SimpleDateFormat("yy/MM/dd");
    TimeZone tz = TimeZone.getTimeZone(Config.TIME_ZONE);
    String date = sdf.format(Calendar.getInstance(tz).getTime());
    int spacePosition1 = 0;
    int spacePosition2 = 0;
    int i = 0;
    while (i < text.length) {
      if (text[i] == 0 && text[i + 1] == 0)
        if (spacePosition1 == 0) {
          spacePosition1 = i;
        } else if (spacePosition1 != 0 && spacePosition2 == 0) {
          spacePosition2 = i;
          break;
        }  
      i += 2;
    } 
    int subjectLength = spacePosition1 + 2;
    int contentLength = spacePosition2 - spacePosition1;
    if (contentLength <= 0)
      contentLength = 1; 
    byte[] subject = new byte[subjectLength];
    byte[] content = new byte[contentLength];
    System.arraycopy(text, 0, subject, 0, subjectLength);
    System.arraycopy(text, subjectLength, content, 0, contentLength);
    LetterTable.getInstance().writeLetter(itemObjectId, code, sender, receiver, date, 0, subject, content);
  }
}
